import * as vscode from "vscode"
import * as fs from "fs"
import * as path from "path"
import * as os from "os"
import { MachineIdResetter } from "./machineIdResetter"
import { CursorUserChanger } from "./cursorUserChanger"
import { AugmentCleaner } from "./augmentCleaner"
import { DirectoryDeleter } from "./directoryDeleter"
import { CurrentUserGetter } from "./currentUserGetter"
import { CursorAccessTokenGetter } from "./cursorAccessTokenGetter"

export class DashboardProvider implements vscode.WebviewViewProvider {
  private context: vscode.ExtensionContext
  private webviewView?: vscode.WebviewView

  constructor(context: vscode.ExtensionContext) {
    this.context = context
  }

  public resolveWebviewView(
    webviewView: vscode.WebviewView,
    context: vscode.WebviewViewResolveContext,
    _token: vscode.CancellationToken
  ) {
    this.webviewView = webviewView

    webviewView.webview.options = {
      enableScripts: true
    }

    webviewView.webview.html = this.getHtmlContent()

    // 监听来自webview的消息
    webviewView.webview.onDidReceiveMessage(
      async message => {
        console.log("收到消息:", message)
        switch (message.type) {
          case "getPaths":
            // 发送默认路径给webview
            const baseDir = path.join(os.homedir(), "AppData", "Roaming", "Cursor")
            console.log("发送默认路径:", baseDir)
            webviewView.webview.postMessage({
              type: "paths",
              data: {
                baseDir: baseDir
              }
            })
            break
          case "showMessage":
            this.handleShowMessage(message.data)
            break
          case "getCurrentUser":
            await this.handleGetCurrentUser(message.data)
            break
          case "login":
            vscode.window.showInformationMessage(`Token: ${message.token}`)
            break
          case "changeUser":
            try {
              await this.handleChangeUser(message.data)
              // 只有切换成功才刷新显示（但由于会重新加载窗口，这行实际不会执行）
              await this.handleGetCurrentUser(message.data)
            } catch (error) {
              // 错误已在 handleChangeUser 中处理，这里只是防止后续操作
              console.error("用户切换操作失败")
            }
            break
          case "cleanAugment":
            await this.handleCleanAugment(message.data)
            break
          case "deleteDirectory":
            await this.handleDeleteDirectory(message.data)
            break
          case "resetMachineId":
            await this.handleResetMachineId(message.paths)
            break
          case "getAccessToken":
            await this.handleGetAccessToken(message.data)
            break
        }
      },
      undefined,
      this.context.subscriptions
    )
  }

  private getHtmlContent(): string {
    const htmlPath = path.join(this.context.extensionPath, "src", "dashboard.html")
    const html = fs.readFileSync(htmlPath, "utf8")
    return html
  }

  private handleShowMessage(data?: any) {
    if (!data || !data.message) {
      return
    }

    const message = data.message
    const messageType = data.messageType || "info"

    switch (messageType) {
      case "error":
        vscode.window.showErrorMessage(message)
        break
      case "warning":
        vscode.window.showWarningMessage(message)
        break
      case "info":
      default:
        vscode.window.showInformationMessage(message)
        break
    }
  }

  private async handleResetMachineId(paths?: any) {
    console.log("=== handleResetMachineId 被调用 ===")

    // 先确认
    const choice = await vscode.window.showWarningMessage(
      "确定要重置机器ID？",
      { modal: true },
      "确定"
    )

    if (choice !== "确定") {
      console.log("用户取消操作")
      return
    }

    console.log("用户确认，开始重置")
    try {
      console.log("显示开始消息")
      vscode.window.showInformationMessage("正在重置机器ID...")

      // 使用用户提供的baseDir或默认路径
      const baseDir = paths?.baseDir || path.join(os.homedir(), "AppData", "Roaming", "Cursor")
      const machineIdPath = path.join(baseDir, "machineId")
      const storagePath = path.join(baseDir, "User", "globalStorage", "storage.json")
      const sqlitePath = path.join(baseDir, "User", "globalStorage", "state.vscdb")

      console.log("路径信息:")
      console.log("  machineIdPath:", machineIdPath)
      console.log("  storagePath:", storagePath)
      console.log("  sqlitePath:", sqlitePath)

      // 执行重置
      console.log("创建 MachineIdResetter 实例")
      const resetter = new MachineIdResetter(storagePath, sqlitePath, machineIdPath)

      console.log("开始执行重置...")
      await resetter.resetMachineIds()

      console.log("重置完成")
      vscode.window.showInformationMessage("机器ID重置成功！正在重新加载窗口...")

      // 延迟1秒后重新加载窗口
      setTimeout(() => {
        vscode.commands.executeCommand("workbench.action.reloadWindow")
      }, 1000)
    } catch (error: any) {
      console.error("=== 重置失败 ===")
      console.error("错误:", error)
      console.error("错误消息:", error.message)
      console.error("错误堆栈:", error.stack)
      vscode.window.showErrorMessage(`重置失败: ${error.message}`)
    }
  }

  private async handleChangeUser(data?: any) {
    console.log("=== handleChangeUser 被调用 ===", data)

    if (!data || !data.email || !data.token) {
      vscode.window.showErrorMessage("缺少必要参数：email 和 token")
      return
    }

    // 先确认
    const choice = await vscode.window.showWarningMessage(
      `确定切换Cursor用户吗？\n邮箱: ${data.email}`,
      { modal: true },
      "确定"
    )

    if (choice !== "确定") {
      console.log("用户取消操作")
      return
    }

    console.log("用户确认，开始修改")
    try {
      vscode.window.showInformationMessage("正在修改用户信息...")

      // 使用用户提供的baseDir或默认路径
      const baseDir = data.baseDir || path.join(os.homedir(), "AppData", "Roaming", "Cursor")
      const sqlitePath = path.join(baseDir, "User", "globalStorage", "state.vscdb")

      console.log("数据库路径:", sqlitePath)

      // 执行修改 - 如果修改失败会抛出异常，不会继续执行后续操作
      const changer = new CursorUserChanger()
      const success = await changer.changeCursorUser(sqlitePath, data.email, data.token)

      if (!success) {
        throw new Error("用户切换失败：数据库更新未成功")
      }

      console.log("=== 用户切换成功，重启编辑器 ===")
      vscode.window.showInformationMessage("用户信息修改成功！开始重启编辑器...")

      // 延迟1秒后退出编辑器
      setTimeout(() => {
        vscode.commands.executeCommand("workbench.action.quit")
      }, 1000)

      // // 延迟1秒后重新加载窗口
      // setTimeout(() => {
      //   vscode.commands.executeCommand("workbench.action.reloadWindow")
      // }, 1000)
    } catch (error: any) {
      console.error("=== 修改失败 ===")
      console.error("错误:", error)
      console.error("错误堆栈:", error.stack)
      vscode.window.showErrorMessage(`用户切换失败: ${error.message}`)

      // 切换失败时不刷新用户信息显示
      throw error
    }
  }

  private async handleCleanAugment(data?: any) {
    console.log("=== handleCleanAugment 被调用 ===", data)

    // 先确认
    const choice = await vscode.window.showWarningMessage(
      "确定要清理所有Augment数据吗？此操作不可恢复。",
      { modal: true },
      "确定"
    )

    if (choice !== "确定") {
      console.log("用户取消操作")
      return
    }

    console.log("用户确认，开始清理")
    try {
      vscode.window.showInformationMessage("正在清理Augment数据...")

      // 使用用户提供的baseDir或默认路径
      const baseDir = data?.baseDir || path.join(os.homedir(), "AppData", "Roaming", "Cursor")
      const sqlitePath = path.join(baseDir, "User", "globalStorage", "state.vscdb")

      console.log("数据库路径:", sqlitePath)

      // 执行清理
      const cleaner = new AugmentCleaner()
      const deletedCount = await cleaner.cleanAugmentData(sqlitePath)

      vscode.window.showInformationMessage(`清理成功！已删除 ${deletedCount} 条Augment数据。`)
    } catch (error: any) {
      console.error("=== 清理失败 ===")
      console.error("错误:", error)
      vscode.window.showErrorMessage(`清理失败: ${error.message}`)
    }
  }

  private async handleDeleteDirectory(data?: any) {
    console.log("=== handleDeleteDirectory 被调用 ===", data)

    if (!data || !data.dirType) {
      vscode.window.showErrorMessage("缺少必要参数：dirType")
      return
    }

    const dirNames: { [key: string]: string } = {
      workspaceStorage: "workspaceStorage",
      history: "history",
      globalStorage: "globalStorage"
    }

    const dirName = dirNames[data.dirType]
    if (!dirName) {
      vscode.window.showErrorMessage(`无效的目录类型: ${data.dirType}`)
      return
    }

    // 先确认
    const choice = await vscode.window.showWarningMessage(
      `确定要删除 ${dirName} 目录吗？此操作不可恢复！`,
      { modal: true },
      "确定"
    )

    if (choice !== "确定") {
      console.log("用户取消操作")
      return
    }

    console.log("用户确认，开始删除")
    try {
      vscode.window.showInformationMessage(`正在删除 ${dirName} 目录...`)

      // 使用用户提供的baseDir或默认路径
      const baseDir = data.baseDir || path.join(os.homedir(), "AppData", "Roaming", "Cursor")
      const targetDir = path.join(baseDir, "User", dirName)

      console.log("目标目录:", targetDir)

      // 执行删除
      const deleter = new DirectoryDeleter()
      await deleter.deleteDirectory(targetDir)

      vscode.window.showInformationMessage(`${dirName} 目录删除成功！`)
    } catch (error: any) {
      console.error("=== 删除失败 ===")
      console.error("错误:", error)
      vscode.window.showErrorMessage(`删除失败: ${error.message}`)
    }
  }

  private async handleGetCurrentUser(data?: any) {
    console.log("=== handleGetCurrentUser 被调用 ===")

    try {
      // 使用用户提供的baseDir或默认路径
      const baseDir = data?.baseDir || path.join(os.homedir(), "AppData", "Roaming", "Cursor")
      const sqlitePath = path.join(baseDir, "User", "globalStorage", "state.vscdb")

      console.log("数据库路径:", sqlitePath)

      // 获取当前用户
      const getter = new CurrentUserGetter()
      const email = await getter.getCurrentUser(sqlitePath)

      // 发送结果给webview
      if (this.webviewView) {
        this.webviewView.webview.postMessage({
          type: "currentUser",
          data: { email }
        })
      }
    } catch (error: any) {
      console.error("=== 获取当前用户失败 ===")
      console.error("错误:", error)
      // 发送空结果
      if (this.webviewView) {
        this.webviewView.webview.postMessage({
          type: "currentUser",
          data: { email: null }
        })
      }
    }
  }

  private async handleGetAccessToken(data: { email: string; cookieToken: string }) {
    console.log("=== handleGetAccessToken 被调用 ===", data)

    if (!data || !data.cookieToken) {
      vscode.window.showErrorMessage("缺少必要参数：cookieToken")
      // 发送失败结果给 webview
      if (this.webviewView) {
        this.webviewView.webview.postMessage({
          type: "accessTokenResult",
          data: { success: false, error: "缺少 cookieToken 参数" }
        })
      }
      return
    }

    try {
      vscode.window.showInformationMessage("正在获取 AccessToken...")

      // 创建 AccessToken 获取器
      const getter = new CursorAccessTokenGetter()
      const result = await getter.getAccessToken(data.cookieToken)

      console.log("AccessToken 获取成功:", {
        accessToken: result.accessToken.substring(0, 30) + "...",
        email: data.email
      })

      vscode.window.showInformationMessage(
        `✅ AccessToken 获取成功！\n邮箱: ${data.email || "未知"}`
      )

      // 发送成功结果给 webview
      if (this.webviewView) {
        this.webviewView.webview.postMessage({
          type: "accessTokenResult",
          data: {
            success: true,
            accessToken: result.accessToken,
            email: data.email
          }
        })
      }
    } catch (error: any) {
      console.error("=== 获取 AccessToken 失败 ===")
      console.error("错误:", error)
      vscode.window.showErrorMessage(`获取 AccessToken 失败: ${error.message}`)

      // 发送失败结果给 webview
      if (this.webviewView) {
        this.webviewView.webview.postMessage({
          type: "accessTokenResult",
          data: { success: false, error: error.message }
        })
      }
    }
  }
}
